using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FrameWork.Source.FrameWork;

namespace Boomer.Source.FrameWork.State_and_Screen_Manager.Screen_Manager
{
    class ScreenManager
    {
        private List<IScreen> m_pListScreen;

        private bool m_isInitialize;

        struct ScreenInfo
        {
            public int index;
            public bool isOverlap;
            public bool hasFocus;

            public ScreenInfo(int index, bool isOverlap , bool hasFocus)
            {
                this.index = index;
                this.isOverlap = isOverlap;
                this.hasFocus = hasFocus;
            }
        }

        private List<ScreenInfo> m_pListInfo;

        private bool m_isNextScreen;

        public StateManager m_pStateManager;

        public ScreenManager(StateManager pState)
        {
            m_pListScreen = new List<IScreen>();
            m_isInitialize = false;

            m_pListInfo = new List<ScreenInfo>();
            m_isNextScreen = false;

            m_pStateManager = pState;
        }


        public void addScreen(IScreen pScreen)
        {
            m_pListScreen.Add(pScreen);
        }

        public void init()
        {
            if (!m_isInitialize)
            {
                foreach (IScreen screen in m_pListScreen)
                {
                    if (screen.m_isActive)
                    {
                        screen.init();
                        screen.m_isInitialize = true;
                    }
                }
            }
        }

        public void update(float deltaTime)
        {
            if (m_isNextScreen )
            {
                nextScreen();
                m_isNextScreen = false;
            }
            foreach (IScreen screen in m_pListScreen)
            {
                if (screen.m_isActive && !screen.m_isNotUpdate)
                {
                    screen.update(deltaTime);
                    if (screen.m_isFocusable)
                        screen.processInput(deltaTime);
                }
            }
        }

        public void render()
        {
            foreach (IScreen screen in m_pListScreen)
            {
                if (screen.m_isActive)
                {
                    screen.render();
                }
            }
        }

        public void setScreen(string strScreenName , bool isOverlap , bool hasFocus)
        {
            IScreen screen = getScreenByName(strScreenName);
            if (screen == null)
                return;
            ScreenInfo info = new ScreenInfo(screen.m_nIndex, isOverlap , hasFocus);
            m_pListInfo.Add(info);
            m_isNextScreen = true;
        }

        public void setScreen(int screenIndex , bool isOverlap, bool hasFocus)
        {
            IScreen screen = getScreenByIndex(screenIndex);
            if (screen == null)
                return;
            ScreenInfo info = new ScreenInfo(screen.m_nIndex, isOverlap , hasFocus);
            m_pListInfo.Add(info);
            m_isNextScreen = true;
        }

        private void nextScreen()
        {
            int count = m_pListInfo.Count;
            for (int i = 0; i < count; ++i)
            {
                IScreen screen = getScreenByIndex(m_pListInfo[i].index);
                if (screen == null)
                    return;
                if( m_pListInfo[i].hasFocus || !m_pListInfo[i].isOverlap )
                    unFocus(m_pListInfo[i].isOverlap , m_pListInfo[i].hasFocus);
                if( m_pListInfo[i].hasFocus )
                    screen.m_isFocusable = true;
                screen.m_isActive = true;
                if (!screen.m_isInitialize)
                    screen.init();
            }
            m_pListInfo.Clear();
        }

        private void unFocus(bool isOverlap , bool hasFocus)
        {
            foreach (IScreen screen in m_pListScreen)
            {
                if (screen.m_isFocusable && ( hasFocus || !isOverlap ))
                {
                    screen.m_isFocusable = false;
                }
                if (!isOverlap)
                {
                    screen.m_isActive = false;
                }
            }
        }

        public IScreen getScreenByName(string strScreenName)
        {
            foreach (IScreen screen in m_pListScreen)
            {
                if (screen.m_strScreenName == strScreenName)
                    return screen;
            }

            return null;
        }

        public IScreen getScreenByIndex(int screenIndex)
        {
            foreach (IScreen screen in m_pListScreen)
            {
                if (screen.m_nIndex == screenIndex)
                    return screen;
            }

            return null;
        }
    }
}
